//#define __FORCE_TRACE__
//#define __FORCE_DEBUG__
//#define __FORCE_INFO__
#define THIS_FILE "net\fn_addevent.sqf"
#include <tmf_constants.h>
#include <tmf_macros.h>

TRACE_1("Start",_this);
private ["_Target","_bAllowed", "_sEventName", "_cEventCode", "_aEventHandlers"];
// We can call the function either with numbers of text, I find text more clear
// The goal of the code below is to check if the code is run on the intended target system and then either set the variable to True or False.
// ex: We want to set the event "GlobalChat" which only make sense on Player computers, so we'll do  ["CLIENT", "GlobalChar", {code}] call XNetAddEvent;
//     The result is that it will be added to the g_oEventHolder ONLY if the code is executing on a client. On a server, _bAllowed will be false.
DEFAULT_PARAM(_Target,0,"");
DEFAULT_PARAM(_sEventName,1,"");
DEFAULT_PARAM(_cEventCode,2,{});

_bAllowed = false;
If (typeName(_this select 0) == "STRING") then {
	_bAllowed = switch (_this select 0) do {
		case "ALL": {true}; // all
		case "SERVER": {if (isServer) then {true} else {false}}; // server only
		case "CLIENT": {if ((isServer && !isDedicated) || (!isDedicated && !isServer)) then {true} else {false}}; // client only
		case "DEDICATED": {if (isDedicated) then {true} else {false}}; // dedicated only
		case "CLIENT2": {if (!isServer) then {true} else {false}}; // client only, 2
		case "HEADLESS": {if (!isDedicated && !hasInterface) then {true} else {false}}; // headless client
	};	
} else {
	_bAllowed = switch (_this select 0) do {
		case 0: {true}; // all
		case 1: {if (isServer) then {true} else {false}}; // server only
		case 2: {if ((isServer && !isDedicated) || (!isDedicated && !isServer)) then {true} else {false}}; // client only
		case 3: {if (isDedicated) then {true} else {false}}; // dedicated only
		case 4: {if (!isServer) then {true} else {false}}; // client only, 2
		case 5: {if (!isDedicated && !hasInterface) then {true} else {false}}; // headless client
	};	
};

if (_bAllowed) then {
	// Instancied variables for readability.
	// 1. We retrieve the list of existing event handlers.
	_aEventHandlers = GVAR(event_holder) getVariable (_sEventName);
	// 2. If no event handlers have been defined so far, we make a new list of event handlers
	//    A list of handlers is better than a single one, in order to be able to add specific handlers
	//    for new modules without the need to touch the old code.
	//    Ex: You deploy your MHQ, you can have 3 handlers: 1) Sets the marker name to deployed. 2) Sends a radio message to everyone. 3) Lock the vehicle.
	if (isNil "_aEventHandlers") then {_aEventHandlers = []};
	// 3. We add the event handler to the list. The set [count.. is a nice trick to add to an array.
	_aEventHandlers set [count _aEventHandlers, _cEventCode];
	// 4. We overwrite the event handlers list present on the object with the updated one.
	GVAR(event_holder) setVariable [_sEventName, _aEventHandlers];
	TRACE_1("AddedHandler", [_sEventName, count _aEventHandlers]);
};
